home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_7.zip
/
ADAVIO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-13
|
12KB
|
353 lines
/*
HELP ENGINE PARA GWADA
Módulo ADAVIO.C
Rotinas específicas para escrita direta na memória de vídeo
Trabalho de conclusao
Bacharelado em Informática
Ulrich Peters
Rafael Presotto
Jerry Dressler
*/
#include "..\source\adavio.h"
#include <dos.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
typedef VEL far * VPFAR; /* pointer para memória de vídeo */
typedef struct windes WINDES; /* descritor de janela */
typedef WINDES * WIPTR; /* pointer para descritor */
#define VOFS(x,y) ( col_vis * ( y ) + ( x ) )
#define VPOS(x,y) (VPFAR) ( vstart + VOFS( x, y ) )
#define WINDESLEN ( sizeof(struct windes) )
#define VELLEN ( sizeof( VEL ) )
struct windes { /* Descritor de janela */
int x1, y1, /* Vértices da janela */
x2, y2,
curs, curz; /* Posiçao do cursor antes da abertura */
VEL *winmem; /* Pointer para o buffer */
};
VPFAR vstart; /* ponteiro ao primeiro caractere na VRAM */
int vlinha, /* armazena a posicao atual do cursor */
vcoluna,
viewx1, /* canto superior esquerdo da janela */
viewy1,
viewx2, /* canto inferior direito da janela */
viewy2,
lin_vis = 25, /* numero de linhas */
col_vis = 80, /* numero de colunas */
winopen = 0; /* numero de janelas abertas */
char vkarte, /* codigo do sistema de video */
color; /* é 1 se placa pode mostrar cores */
WIPTR winptr; /* pointer para descritor de janela */
/* Funcao inicial, determina o sistema de video
e seta as variavel do modulo de video */
void VioInit( void )
{
static char vmode[] = {
MDA, CGA, 0, EGA, EGA_MONO, 0,
VGA_MONO, VGA, 0, MCGA, MCGA_MONO,
MCGA
};
static char egamode[] = {
EGA, EGA, EGA_MONO,
};
union REGS regs; /* registradores para chamada de interrupcao */
vkarte = 0xff; /* ainda sem placa definida */
/* Testar se é placa VGA ou MCGA */
regs.x.ax = 0x1a00;
int86(0x10, ®s, ®s);
if ( regs.h.al == 0x1a ) /* VGA ou MCGA? */
{ /* sim */
vkarte = vmode[ regs.h.bl-1 ];
color = (char) !( vkarte==MDA || vkarte==EGA_MONO );
}
else /* nao */
{
regs.h.ah = 0x12; /* testar se é EGA */
regs.h.bl = 0x10;
int86(0x10, ®s, ®s);
if ( regs.h.bl != 0x10 )
{ /* é sim */
vkarte = egamode[ (regs.h.cl >> 1) % 3 ];
color = (char) ( vkarte != EGA_MONO );
}
}
/* definir ponteiro para memoria de video */
regs.h.ah = 15;
int86(0x10, ®s, ®s); /* determinar modo atual de video */
vstart = (VPFAR) MK_FP((regs.h.al!=7) ? 0xb800 : 0xb000, 0);
if ( vkarte == 0xff ) /* placa nao é EGA, VGA nem MCGA? */
{ /* nao */
color = (char) ( regs.h.al != 7 );
vkarte = (char) (( color ) ? CGA : MDA);
}
else /* é, determinar numero de linhas */
lin_vis = *((char far *) MK_FP( 0x40, 0x84 )) + 1;
if ( regs.h.al==0 || regs.h.al==2 )
color = 0; /* monitor colorido em modo P/B */
col_vis = *((char far *) MK_FP( 0x40, 0x4a )); /* colunas */
regs.h.ah = 5; /* definir pagina de video atual = 0 */
regs.h.al = 0;
int86(0x10, ®s, ®s);
regs.h.ah = 3; /* determinar posicao do cursor */
regs.h.bh = 0;
int86(0x10, ®s, ®s);
vlinha = regs.h.dh;
vcoluna = regs.h.dl;
VioSetView(0, 0, col_vis-1, lin_vis-1);
winptr = (WIPTR) malloc( 1 );
}
/* Salva as coordenadas da janela atual */
void VioSetView( int x1, int y1, int x2, int y2 )
{
viewx1 = x1; /* anotar coordenadas */
viewy1 = y1;
viewx2 = x2;
viewy2 = y2;
}
/* Copia uma janela da tela para um buffer */
void VioGet( int x1, int y1, int x2, int y2, VEL far * bptr )
{
int nbytes; /* numero de bytes a copiar por linha */
VPFAR vioptr; /* ponteiro a memoria de video */
nbytes = ( x2 - x1 + 1 ) * VELLEN; /* bytes por linha */
for ( ; y1 <= y2; ++y1 )
{
vioptr = VPOS(x1, y1); /* apontar para o primeiro byte da linha */
MOVE( vioptr, bptr, nbytes);
(char far *) bptr += nbytes;
}
}
/* Coloca um buffer de volta na tela
(restaura uma janela fechada) */
void VioPut( int x1, int y1, int x2, int y2, VEL far * bptr )
{
int nbytes; /* numero de bytes a copiar por linha */
VPFAR vioptr; /* ponteiro a memoria de video */
nbytes = ( x2 - x1 + 1 ) * VELLEN;
for ( ; y1 <= y2; ++y1 )
{
vioptr = VPOS(x1, y1);
MOVE( bptr, vioptr, nbytes);
(char far *) bptr += nbytes;
}
}
/* Abre uma janela na tela, salva texto "abaixo" desta regiao */
int VioWinOpen( int x1, int y1, int x2, int y2 )
{
VEL * bptr; /* buffer */
WIPTR wptr; /* vetor com descritores de janela */
/* alocar buffer */
if ( (bptr = (VEL *) malloc(BUFLEN( x1, y1, x2, y2 ))) != (VEL *) 0 )
{
wptr = (WIPTR) realloc(winptr, WINDESLEN * (winopen+1));
if ( wptr )
{
winptr = wptr; /* endereco novo do vetor */
(wptr += winopen)->x1 = x1; /* anotar coordenadas */
wptr->x2 = x2;
wptr->y1 = y1;
wptr->y2 = y2;
wptr->curs = vcoluna;
wptr->curz = vlinha; /* salvar tambem a posicao do cursor na janela */
VioGet( x1, y1, x2, y2, wptr->winmem = bptr );
++winopen;
return 1;
}
else /* sem memoria para vetor */
{
free( bptr ); /* liberar buffer */
return 0; /* erro */
}
}
else /* faltou espaco para buffer */
return 0;
}
/* Fecha a ultima janela aberta (inf. no vetor de janelas)
e restaura o conteudo anterior se redraw != 0 */
void VioWinClose( int redraw )
{
WIPTR wptr; /* vetor dos descritores de janela */
if (winopen) /* tem uma janela aberta? */
{
wptr = winptr + winopen - 1;
if ( redraw ) /* restaurar tela? */
{
VioPut( wptr->x1, wptr->y1, wptr->x2,
wptr->y2, wptr->winmem );
VioSetCursor( wptr->curs, wptr->curz ); /* cursor na posicao anterior */
}
free( (void *) wptr->winmem ); /* liberar descritor */
/* atualizar vetor dos descritores */
winptr = (WIPTR) realloc(winptr, WINDESLEN*(--winopen)+1);
}
}
/* Leva o cursor a posicao (coluna,linha) por interrupcao
do BIOS ( é mais rapido que gotoxy() ) */
void VioSetCursor( int coluna, int linha )
{
union REGS regs;
regs.h.ah = 2; /* Set Cursor */
regs.h.bh = 0; /* Pag de video 0 */
regs.h.dh = (char) (vlinha = linha);
regs.h.dl = (char) (vcoluna = coluna);
int86(0x10, ®s, ®s);
}
/* Escreve diretamente na memoria de video o texto especificado por "string",
na posicao "coluna,linha" e na cor especificada por "cor".
O byte "cursor" define se o cursor deverá ser levado até a posicao nova */
void VioPrint( int coluna, int linha, char cor,
char cursor, char * string )
{
register VPFAR lptr;
int newpos; /* posicao do cursor como offset */
newpos = coluna + linha * col_vis;
lptr = VPOS(coluna, linha);
for ( ; *string ; ++newpos, ++lptr)
{
lptr->h.caractere = *(string++);
lptr->h.atributo = cor;
}
if ( cursor ) /* mostrar cursor na posicao atual? */
VioSetCursor( newpos % col_vis, newpos / col_vis );
}
/* Fornece saida formatada diretamente na memoria de video,
usando a sintaxe de VioPrint */
void VioPrintf( int coluna, int linha, char cor,
char cursor, char * string, ... )
{
va_list parametros; /* lista de parametros para as marcos va_... */
char saida[255]; /* buffer para o string formatado */
va_start( parametros, string ); /* processar parametros */
vsprintf( saida, string, parametros ); /* formatar string */
VioPrint( coluna, linha, cor, cursor, saida );
}
/* Enche um buffer com num ocorrencias de caractere
sendo num < 133 */
char *VioStrep( char caractere, int num )
{
static char buf[133];